import asyncio

import aioredis

import settings
from bot.insurance_planner_gpt.config.conf import profile_


class HzAsyncRedisHelper:
    _instance = None
    _is_init = False

    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
            cls._instance = super(HzAsyncRedisHelper, cls).__new__(cls)
        return cls._instance

    def __init__(self, host=profile_['redis']['host'], port=profile_['redis']['port'], db=0,
                 password=profile_['redis']['pwd']):
        if HzAsyncRedisHelper._is_init:
            return
        if not settings.ONLINE:
            host = profile_['redis']['local_host']
        self.host = host
        self.port = port
        self.db = db
        self.password = password
        self.connection = asyncio.run(self.get_redis_conn())

    async def get_redis_conn(self):
        return await aioredis.from_url(
            f'redis://{self.host}:{self.port}',
            db=self.db,
            password=self.password,
            encoding='utf-8'
        )

    async def set(self, key, value):
        await self.connection.set(key, value)

    async def get(self, key):
        return await self.connection.get(key)

    async def delete(self, key):
        await self.connection.delete(key)

    async def keys(self, pattern):
        return await self.connection.keys(pattern)

    async def incr_and_expire(self, key, expire):
        count = await self.connection.incr(key)
        await self.connection.expire(key, expire)
        return count

    async def set_time(self, key, value, expire=600):
        return await self.connection.set(key, value, ex=expire, nx=False)

    async def set_nx(self, key, value, expire=600):
        return await self.connection.set(key, value, ex=expire, nx=True)

    async def getListLeftPop(self, key):
        return await self.connection.lpop(key)

    async def setListRightPush(self, key, value):
        await self.connection.rpush(key, value)
